package com.ipan.kits.mapper;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.Reader;
import java.nio.charset.Charset;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;

import org.apache.commons.csv.CSVFormat;
import org.apache.commons.csv.CSVParser;
import org.apache.commons.csv.CSVPrinter;

/**
 * Excel导出的CSV文件处理工具
 * 
 * @author iPan
 * @date 2021-12-17
 */
public class ExcelCsvMapper {

	private static final ExcelCsvMapper ME = new ExcelCsvMapper();
	
	private CSVFormat format = null;
	
	public static ExcelCsvMapper me() {
		return ME;
	}
	
	/**
	 * 根据项目情况，创建自定义风格；
	 */
	public static ExcelCsvMapper create(CSVFormat format) {
		return new ExcelCsvMapper(format);
	}
	
	public static void close(CSVParser parser) {
		if (parser != null) {
			try {
				parser.close();
			} catch (IOException e) {
			}
		}
	}
	public static void close(CSVPrinter printer) {
		if (printer != null) {
			try {
				printer.close();
			} catch (IOException e) {
			}
		}
	}
	
	public ExcelCsvMapper() { // 默认风格，本系统使用的默认风格，避免每次使用都去设置格式；
		format = CSVFormat.EXCEL.builder()
				.setAutoFlush(true) // 实际autoFlush=false，默认情况下BufferWriter在close时候也会自动flush
				.setTrim(true) // 自动对单元格做首尾trim
				.setCommentMarker('#') // 支持#xxx注释
				.build(); // 使用EXCEL配置基础上修改
	}

	public ExcelCsvMapper(CSVFormat format) { // 自定义风格
		this.format = format;
	}
	
	/**
	 * 根据输入流创建解析器
	 */
	public CSVParser parse(final Reader reader) throws IOException {
        return new CSVParser(reader, format);
    }
	/**
	 * 根据文件路径与编码创建解析器
	 */
	public CSVParser parse(final Path path, final Charset charset) throws IOException {
        return new CSVParser(Files.newBufferedReader(path, charset), format);
    }
	/**
	 * 根据文件路径与编码创建解析器
	 */
	public CSVParser parse(final String filePath, final Charset charset) throws IOException {
		Path path = Paths.get(filePath);
        return new CSVParser(Files.newBufferedReader(path, charset), format);
    }
	
	/**
	 * 根据文件输出流创建写入器
	 */
	public CSVPrinter print(final Appendable out) throws IOException {
        return new CSVPrinter(out, format);
    }

	/**
	 * 根据文件与编码创建写入器
	 */
	public CSVPrinter print(final File out, final Charset charset) throws IOException {
        // The writer will be closed when close() is called.
        return new CSVPrinter(new OutputStreamWriter(new FileOutputStream(out), charset), format);
    }
	
	/**
	 * 根据路径与编码创建写入器
	 */
	public CSVPrinter print(final Path out, final Charset charset) throws IOException {
        return print(Files.newBufferedWriter(out, charset));
    }
	
	/**
	 * 根据路径字符串与编码创建写入器
	 */
	public CSVPrinter print(final String filePath, final Charset charset) throws IOException {
		Path path = Paths.get(filePath);
        return print(Files.newBufferedWriter(path, charset));
    }
	
	/**
	 * 创建控制器写入器
	 */
	public CSVPrinter printer() throws IOException {
        return new CSVPrinter(System.out, format);
    }

	//-- 根据写入流做写入操作 --//
	/**
	 * 按单元格写入
	 */
	public void print(final Object value, final Appendable out, final boolean newRecord) throws IOException {
		format.print(value, out, newRecord);
    }
	/**
	 * 写入行分隔符
	 */
	public void println(final Appendable appendable) throws IOException {
		format.println(appendable);
    }
	/**
	 * 写入一行数据
	 */
	public void printRecord(final Appendable appendable, final Object... values) throws IOException {
        for (int i = 0; i < values.length; i++) {
            print(values[i], appendable, i == 0);
        }
        println(appendable);
    }
	
}
